import os
import datetime
from functools import wraps

from flask import render_template
from flask import request #负责接收数据的参数
from flask import redirect #跳转页面
from flask import session
from FlaskPro import csrf


from FlaskPro.OAPrint import oaPro
from FlaskPro.models import *
from FlaskPro.OAPrint.forms import *



def valid_person(fun):
    @wraps(fun)
    def inner(*args, **kwargs):
        user_id = request.cookies.get("user_id")
        user = Person.query.get(int(user_id))
        user_positon = user.per_pos.id

        boss = Position.query.filter_by(p_name="董事长").first()
        hr = Position.query.filter_by(p_name = "HR").first()

        if user_positon in [hr.id,boss.id]:
            return fun(*args, **kwargs)
        else:
            return "抱歉，你没有访问这个页面的权限"
    return inner






def loginValid(fun):
    @wraps(fun) #这个装饰器可以保证被装饰后采用原理的名字
    def inner(*args,**kwargs):
        username = request.cookies.get("user_name")  # 从cookie当中获取数据
        user_id = request.cookies.get("user_id")
        s_user_id = session.get("user_id") #获取session当中的值
        user = Person.query.filter_by(per_id=username, id=user_id).first()  # 开始检测cookie的是否正确
        if user:
            return fun(*args,**kwargs)
        else:
            return redirect("/login/")
    return inner


@oaPro.route("/depart/")
@loginValid
def depart():
    depart_list = Department.query.all()
    return render_template("department.html",**locals())

@oaPro.route("/add_department/",methods = ["GET","POST"])
@loginValid
def add_department():
    if request.method == "POST":
        #request.method 返回请求的方式，注意，页面加载是get请求
        d_name = request.form.get("d_name")
        desc = request.form.get("description")

        #保存数据
        dep = Department()
        dep.d_name = d_name
        dep.d_description = desc
        dep.save()

        return redirect("/depart/")
    return render_template("add_department.html")

@oaPro.route("/edit_department/<int:d_id>/",methods = ["GET","POST"])
@loginValid
def edit_department(d_id):
    d = Department.query.get(d_id)
    if request.method == "POST":
        d_name = request.form.get("name")
        d_description = request.form.get("description")

        d.d_name = d_name
        d.d_description = d_description
        d.update()
        return redirect("/depart/")
    return render_template("edit_department.html",**locals())

@oaPro.route("/del_department/<int:d_id>/")
@loginValid
def del_department(d_id):
    d = Department.query.get(d_id)
    d.delete()
    return redirect("/depart/")

@oaPro.route("/position/<int:d_id>/",methods = ["GET","POST"])
@loginValid
def position(d_id):
    #查询当前部门对于的所有职位
    d = Department.query.get(d_id)
    if request.method == "POST":
        p_id = request.form.get("p_id")
        name = request.form.get("name")
        level = request.form.get("level")
        if p_id: #如果pid有值
            p = Position.query.get(p_id) #获取当前数据
        else: #如果pid没有值
            p = Position() #创建一条新的数据
        #保存职位信息
        p.p_name = name
        p.p_level = level
        p.p_department = d_id
        p.save()
    # 部门所有对应的职位
    p_list = d.d_position
    return render_template("position.html",**locals())

@oaPro.route("/del_position/<int:p_id>/")
@loginValid
def del_position(p_id):
    p = Position.query.get(p_id)
    p.delete()
    url = request.referrer
    print(url)
    return redirect(url)

from flask import jsonify

@oaPro.route("/get_position/<int:p_id>/")
@loginValid
def get_position(p_id):
    p = Position.query.get(p_id) #获取数据
    result = {"id": p.id,"p_name": p.p_name,"p_level": p.p_level} #定义返回字典
    return jsonify(result) #封装为json进行返回


@oaPro.route("/person/")
@valid_person
@loginValid
def person():
    page = int(request.args.get("page",1)) #尝试获取get请求的参数，如果没有，默认为1
    p_list = Person.query.paginate(page, 2)

    if page - 2 <= 0:
        start = 0
    else:
        start = page - 2

    if page+3 > p_list.pages:
        end = p_list.pages
    else:
        end = page + 3


    page_range = list(
        range(1,p_list.pages+1)
    )[start:end]#形成页码列表
    return render_template("person.html",**locals())

import hashlib
def setPassword(password):
    md5 = hashlib.md5() #创建md5实例
    md5.update(password.encode()) #进行加密
    result = md5.hexdigest() #获取加密=结果
    return result


@oaPro.route("/add_person/",methods = ["GET","POST"])
@valid_person
@loginValid
def add_person():
    position_list = Position.query.all()
    department_list = Department.query.all()
    if request.method == "POST":
        #接收前端的数据
        username = request.form.get("username")
        password = request.form.get("password")
        nickname = request.form.get("nickname")
        gender = request.form.get("gender")
        age = request.form.get("age")
        phone = request.form.get("phone")
        email = request.form.get("email")
        address = request.form.get("address")
        department_id = request.form.get("department_id")
        position_id = request.form.get("position_id")
        photo = request.files.get("photo")  # 接收图片需要用request.files接收

        p = Person()
        #保存常规数据
        p.per_name = nickname
        p.per_id = username
        p.password = setPassword(password)
        p.gender = gender
        p.age = age
        p.per_phone = phone
        p.per_email = email
        p.address = address
        p.join_time = datetime.datetime.now()
        p.per_department = department_id
        p.per_position = position_id
        #保存图片
            #保存图片到服务器
        file_name = photo.filename
        static_dir = os.path.join(
            os.path.dirname(
                os.path.dirname(
                    os.path.abspath(__file__)
                )
            )
            ,"static"
        )
        print(static_dir)
        file_path = os.path.join("img",file_name)
        save_path = os.path.join(static_dir,file_path)
        photo.save(save_path) #将图片保存到指定的路径下
            #保存图片路径到数据库
        p.per_photo = file_path
        p.save()
        return jsonify({"result": "success"})
    return render_template("add_person.html",**locals())


@oaPro.route("/")
@loginValid
def index():
    return render_template("index.html")


@csrf.exempt #避免csrf，不进行csrf检测
@oaPro.route("/login/",methods=["GET","POST"])
def login():
    if request.method == "POST":
        username = request.form.get("username")
        password = request.form.get("password")
        if username and password:
            #使用用户提交的用户名和密码进行查询，如果有结果，代表合法 first获取第一个结果
            user = Person.query.filter_by(per_id = username,password = setPassword(password)).first()
            if user:
                response = redirect("/")
                response.set_cookie("user_id",str(user.id))
                response.set_cookie("user_name", user.per_id)
                response.set_cookie("nick_name",user.per_name)
                session["user_id"] = user.id #设置session
                return response
    return render_template("login.html")

@oaPro.route("/logout/")
def logout():
    response = redirect("/login/")
    response.delete_cookie("user_id")
    response.delete_cookie("user_name")
    response.delete_cookie("nick_name")
    del session["user_id"] #删除session
    return response


@oaPro.route("/attendance_me/",methods = ["GET","POST"])
def attendance_me():
    #获取所有直属领导
    #查找自己
    user_id = request.cookies.get("user_id") #通过cookie获取用户id
    my_self = Person.query.get(int(user_id)) #获取id获取个人身份
    #获取部门id
    d_id = my_self.person_deparment.id
    #获取直属领导职级
    p_level = int(my_self.per_pos.p_level)+1
    #查询直属领导的职位(查找所有自己部门职级大于自己一级的职位)
    p_position = Position.query.filter_by(p_level = p_level,p_department = d_id).all()
    #获取所有的直属领导
    leader_list = []
    for p in p_position:
        l_list = [{"name": i.per_name, "id": i.id} for i in p.p_person]
        leader_list.extend(l_list)

    # 接收假条数据
    if request.method == "POST":
        reason = request.form.get("reason")
        a_type = request.form.get("a_type")
        long = request.form.get("a_time") #时长
        a_time = request.form.get("start") #请假时间
        verify_person = request.form.get("verify_person")

    # 保存假条
        # 假条申请中 0 申请中
        attendance = Attendance()
        attendance.a_type = a_type #请假类型
        attendance.a_reason = reason #请假理由
        attendance.a_time = datetime.datetime.strptime(a_time,"%Y-%m-%d") #时间需要按照格式进行转换
        attendance.a_long = long #假条时长
        attendance.a_state = 0 #假条的状态
        attendance.verify_person = verify_person #假条的审核人
        attendance.a_person = user_id #假条申请人，就是当前用户
        attendance.save() #字段数据的错误一定是在save保存
    #假条展示：展示自己的所有假条
    attendance_list = my_self.p_attendance
    return render_template("attendance_me.html",**locals())

@oaPro.route("/attendance_subordinate/")
def attendance_subordinate():
    user_id = request.cookies.get("user_id")
    a_list = Attendance.query.filter_by(
        verify_person = int(user_id)
    ).order_by("a_state","a_time")
    return render_template("attendance_subordinate.html",**locals())


@oaPro.route("/verify/<int:id>/")
def verify(id):
    change = request.args.get("change")
    referer = request.referrer
    if change:
        attendance = Attendance.query.get(id)
        attendance.a_state = int(change)
        attendance.update()
    return redirect(referer)















#定义一个函数
def get_verify_name(id):
    p = Person.query.get(int(id))
    return p.per_name

#将函数按照到app或者蓝图上
#按照蓝图
oaPro.add_app_template_filter(get_verify_name,"v_name")
#安装到app
# app.add_template_filter(get_verify_name,"v_name")


@oaPro.route("/test/",methods = ["GET","POST"])
def test():
    p_list = Person.query.paginate(2,2) #这里返回的是一个分页对象
    print(dir(p_list))
    #'has_next', 'has_prev', 'items', 'iter_pages', 'next', 'next_num', 'page', 'pages', 'per_page', 'prev', 'prev_num', 'query', 'total'
    return render_template("test_page.html",**locals())


@oaPro.route("/test_data/")
def test_data():
    result = {
        "x_data": ["a","b","c","d","e"],
        "y_data": [1,2,5,2,4]
    }
    return jsonify(result)



def get_page():
    """
    全局展示页面的权限 的变量
    """
    result = {
        "news": False,
        "permission": False,
        "subordinate": False,
        "hr": False
    }
    user_id = request.cookies.get("user_id")

    if user_id:
        user = Person.query.get(int(user_id))
        boss = Position.query.filter_by(p_name="董事长").first()

        #董事长和新媒体运营有发布文章的权限
        #获取职位
        user_positon = user.per_pos.id
        news_person = Position.query.filter_by(p_name = "新媒体拓展").first()
        if user_positon in [news_person.id,boss.id]:
            result["news"] = True

        #只有董事长拥有权限管理
        if user_positon == boss.id:
            result["permission"] = True

        #职级大于1才可以有下属考勤
        user_level = user.per_pos.p_level
        if user_level > 1: #>=2
            result["subordinate"] = True

        #HR和boos可以进行人事管理
        hr = Position.query.filter_by(p_name = "HR").first()
        if user_positon in [hr.id,boss.id]:
            result["hr"] = True

    return result


oaPro.add_app_template_global(get_page,"get_page")













# def get_page():
#     return {"name": "老边"}
#
# oaPro.add_app_template_global(get_page,"test_global")





